package com.wms.oms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms.common.core.utils.DateUtils;
import com.wms.oms.domain.Inventory;
import com.wms.oms.domain.InventoryLog;
import com.wms.oms.domain.MoveOrder;
import com.wms.oms.domain.MoveOrderItem;
import com.wms.oms.domain.ProductSku;
import com.wms.oms.enums.ApprovalStatus;
import com.wms.oms.enums.InventoryType;
import com.wms.oms.mapper.MoveOrderItemMapper;
import com.wms.oms.mapper.MoveOrderMapper;
import com.wms.oms.service.IInventoryLogService;
import com.wms.oms.service.IInventoryService;
import com.wms.oms.service.IMoveOrderService;
import com.wms.oms.service.IProductSkuService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;

/**
 * @author zzm
 * @date 2023/8/18
 * @desc
 */
@Service
public class MoveOrderServiceImpl implements IMoveOrderService {

    @Autowired
    private MoveOrderMapper moveOrderMapper;

    @Autowired
    private MoveOrderItemMapper moveOrderItemMapper;

    @Autowired
    private IInventoryService inventoryService;

    @Autowired
    private IProductSkuService productSkuService;

    @Autowired
    private IInventoryLogService inventoryLogService;

    @Override
    public MoveOrder selectMoveOrderById(Long id) {
        return moveOrderMapper.selectById(id);
    }

    @Override
    public List<MoveOrder> selectMoveOrderList(MoveOrder moveOrder) {
        return moveOrderMapper.selectList(new LambdaQueryWrapper<MoveOrder>());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertMoveOrder(MoveOrder moveOrder) {
        moveOrder.setSn("MO"+ DateUtils.getNowDate().getTime());
        moveOrder.setStatus(ApprovalStatus.WAIT_COMMIT.getValue());
        int result = moveOrderMapper.insert(moveOrder);
        List<MoveOrderItem> items = moveOrder.getMoveOrderItemList();
        for (MoveOrderItem item : items) {
            item.setMoveOrderId(moveOrder.getId());
            moveOrderItemMapper.insert(item);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateMoveOrder(MoveOrder moveOrder) {
        int result = moveOrderMapper.updateById(moveOrder);
        List<MoveOrderItem> itemList = moveOrder.getMoveOrderItemList();
        for (MoveOrderItem item : itemList) {
            if (ObjectUtils.isEmpty(item.getId())) {
                item.setMoveOrderId(moveOrder.getId());
                moveOrderItemMapper.insert(item);
            }else {
                moveOrderItemMapper.updateById(item);
            }
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int confirm(MoveOrder moveOrder) {
        MoveOrder model = moveOrderMapper.selectById(moveOrder.getId());
        Assert.notNull(model, "调拨单不能为空!");
        List<MoveOrderItem> itemList = moveOrderItemMapper.selectList(
                new LambdaQueryWrapper<MoveOrderItem>().eq(MoveOrderItem::getMoveOrderId, model.getId()));
        for (MoveOrderItem item : itemList) {
            ProductSku productSku = productSkuService.selectById(item.getSkuId());
            // 调入操作
            Inventory inventoryIn =  inventoryService.selectInventoryByPro(item.getSkuId(), model.getInWarehouseId());
            if (ObjectUtils.isNotEmpty(inventoryIn)) {
                if (inventoryIn.getCheckFlag()) {
                    throw new IllegalArgumentException("库存盘点中,请稍后操作!");
                }
                // 调入数
                inventoryIn.setQty(inventoryIn.getQty().add(item.getQty()));
                inventoryService.updateInventory(inventoryIn);
            }else {
                inventoryIn = new Inventory();
                inventoryIn.setWarehouseId(model.getInWarehouseId());
                inventoryIn.setSkuId(item.getSkuId());
                inventoryIn.setQty(item.getQty());
                inventoryIn.setProductId(productSku.getProductId());
                inventoryService.insertInventory(inventoryIn);
            }
            // 记录库存调入日志
            InventoryLog inventoryLog = new InventoryLog();
            inventoryLog.setInventoryType(InventoryType.MOVE_IN.getValue());
            inventoryLog.setQty(item.getQty());
            inventoryLog.setPrice(productSku.getSalePrice());
            inventoryLog.setSn(model.getSn());
            inventoryLog.setWarehouseId(model.getInWarehouseId());
            inventoryLog.setSkuId(productSku.getId());
            inventoryLogService.insertInventoryLog(inventoryLog);


            // 调出操作
            Inventory inventoryOut =  inventoryService.selectInventoryByPro(item.getSkuId(), model.getOutWarehouseId());
            if (ObjectUtils.isNotEmpty(inventoryOut)) {
                if (inventoryOut.getCheckFlag()) {
                    throw new IllegalArgumentException("库存盘点中,请稍后操作!");
                }
                // 调出数
                inventoryOut.setQty(inventoryIn.getQty().subtract(item.getQty()));
                inventoryService.updateInventory(inventoryIn);
            }else {
                inventoryOut = new Inventory();
                inventoryOut.setWarehouseId(model.getInWarehouseId());
                inventoryOut.setSkuId(item.getSkuId());
                // 取反，直接为负出库
                inventoryOut.setQty(item.getQty().negate());
                inventoryOut.setProductId(productSku.getProductId());
                inventoryService.insertInventory(inventoryOut);
            }

            // 记录库存调出日志
            InventoryLog inventoryLogOut = new InventoryLog();
            inventoryLogOut.setInventoryType(InventoryType.MOVE_OUT.getValue());
            inventoryLogOut.setQty(item.getQty().negate());
            inventoryLogOut.setPrice(productSku.getSalePrice());
            inventoryLogOut.setSn(model.getSn());
            inventoryLogOut.setWarehouseId(model.getOutWarehouseId());
            inventoryLogOut.setSkuId(productSku.getId());
            inventoryLogService.insertInventoryLog(inventoryLogOut);
        }
        // 审批完成
        model.setStatus(ApprovalStatus.APPROVALED.getValue());
        int result = moveOrderMapper.updateById(moveOrder);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteMoveOrderByIds(Long[] ids) {
        MoveOrder moveOrder = new MoveOrder();
        moveOrder.setDelFlag(Boolean.TRUE);
        int result = moveOrderMapper.update(moveOrder,
                new LambdaQueryWrapper<MoveOrder>().in(MoveOrder::getId, ids));
        return result;
    }
}
